import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;

import java.io.*;
import java.util.ArrayList;
import java.util.regex.Pattern;

public class CppParam {
    public String path;
    public CppParam(String path)
    {
        this.path=path;
    }

    public static boolean isInteger(String str)
    {
        if (null == str || "".equals(str))
        {
            return false;
        }
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
        return pattern.matcher(str).matches();
    }


    public static boolean isDouble(String str)
    {
        if (null == str || "".equals(str))
        {
            return false;
        }
        Pattern pattern = Pattern.compile("^[-\\+]?[.\\d]*$");
        return pattern.matcher(str).matches();
    }

    public static  String readFromTextFile(String pathname) throws IOException
    {
        String code="";
        File filename = new File(pathname);
        InputStreamReader reader = new InputStreamReader(new FileInputStream(filename));
        BufferedReader br = new BufferedReader(reader);
        String line = "";
        line = br.readLine();
        while(line != null)
        {
            code+=line+"\n";
            line = br.readLine();
        }
        return code;
    }
    public static void findParamValue(Tree tree,paramSelect ps)
    {
        if(!tree.isEmpty())
        {
            if(tree.getRootData().equals("iterationstatement")&&tree.getChild(0).getRootData().equals("for"))
            {
                if(ps.getSkipFor())
                {
                    System.out.println("****************Skip For Block");
                    findParamValue(tree.getChild(tree.getChildCount() - 1),ps);

                }
            }
            else if(tree.getRootData().equals("selectionstatement")&&tree.getChild(0).getRootData().equals("if"))
            {
                if(ps.getSkipIf())
                {
                    System.out.println("****************Skip If Block");
                    findParamValue(tree.getChild(tree.getChildCount() - 1),ps);

                }
            }
            else if (tree.getRootData().equals("literal") && tree.getChildCount() ==1)
            {
                if (tree.getChild(0).getRootData().equals("booleanliteral") && tree.getChildCount() ==1)
                {
                    Tree paramValue=tree.getChild(0).getChild(0);
                    System.out.print("Bool:"+tree.getChild(0).getChild(0).getRootData());
                    System.out.println();
                    tree=tree.getChild(0).getChild(0);

                }

                else {
                    Tree paramValue = tree.getChild(0);
                    String text=paramValue.getRootData().toString();
                    if(isInteger(text))
                    {
                        System.out.print("Int:"+text);
                        System.out.println();
                    }
                    else if(isDouble(text))
                    {
                        System.out.print("Double:"+text);
                        System.out.println();
                    }
                    else {
                        System.out.print("String:"+text);
                        System.out.println();
                    }

                }
            }
            else if(tree.getRootData().equals("idexpression") && tree.getChildCount() ==1)
            {
                if (tree.getChild(0).getRootData().equals("unqualifiedid") && tree.getChildCount() ==1)
                {
                    if(ps.getSkipVariable())
                    {
                        Tree paramValue = tree.getChild(0).getChild(0);
                        System.out.print("skip Variable:"+paramValue.getRootData());
                        System.out.println();
                        tree=tree.getChild(0).getChild(0);
                    }
                    else {
                        Tree paramValue = tree.getChild(0).getChild(0);
                        System.out.print("Variable:" + paramValue.getRootData());
                        System.out.println();
                        tree=tree.getChild(0).getChild(0);

                    }
                }
            }

            if (tree.getChildCount() > 0)
            {
                for (int i = 0; i < tree.getChildCount(); i++)
                {
                    findParamValue(tree.getChild(i),ps);
                }
            }
        }
    }
    public static void findParamDecl(Tree tree,ArrayList<String> paramNameList,paramSelect ps)
    {
        TreeProcessor tp=new TreeProcessor();
        if(!tree.isEmpty()) {
            if(tree.getRootData().equals("iterationstatement")&&tree.getChild(0).getRootData().equals("for"))
            {
                if(ps.getSkipFor())
                {
                    System.out.println("****************Skip For Block");
                    findParamValue(tree.getChild(tree.getChildCount() - 1),ps);
                    tree=tree.getChild(tree.getChildCount() - 1);
                    return;
                }
            }
            else if(tree.getRootData().equals("selectionstatement")&&tree.getChild(0).getRootData().equals("if"))
            {
                if(ps.getSkipIf())
                {
                    System.out.println("****************Skip If Block");
                    findParamValue(tree.getChild(tree.getChildCount() - 1),ps);
                    tree=tree.getChild(tree.getChildCount() - 1);
                    return;
                }
            }
            else {
                findParamValue(tree,ps);
            }



            if (tree.getChildCount() > 0)
            {
                for (int i = 0; i < tree.getChildCount(); i++)
                {
                    findParamDecl(tree.getChild(i),paramNameList,ps);
                }
            }
        }

    }

    public static void getParamFromCpp(String loadPath, ArrayList<ArrayList<Gene>> populationGeneList, int pn, ArrayList<String> paramNameList) throws IOException {
        TreeProcessor tp=new TreeProcessor();
        String code=readFromTextFile(loadPath);

        ANTLRInputStream input = new ANTLRInputStream(code);
        CPP14Lexer lexer = new CPP14Lexer(input);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        CPP14Parser parser = new CPP14Parser(tokens);
        CPP14Parser.TranslationunitContext tree = parser.translationunit();


        tree.removeLastChild();
        Tree myTree=new Tree(tp.getRuleName(tree,parser));
        tp.convertTree(tree,parser,myTree);

        //paramSelect ps=new paramSelect(false,false,false);
        paramSelect ps=new paramSelect();
        findParamValue(myTree,ps);


    }

    public static void main(String[] args) throws IOException {
        String loadPath="E:\\u\\home\\catkin_ws\\src\\navigation\\global_planner\\src\\planner_core.cpp";
        //getRosParamFromCpp(loadPath);
        //getRosParamFromDir("E:\\u\\home\\catkin_ws\\src\\navigation\\move_base");
        ArrayList<ArrayList<Gene>> populationGeneList=new ArrayList<>();
        ArrayList<String> paramNameList=new ArrayList<>();
        getParamFromCpp(loadPath,populationGeneList,10,paramNameList);

    }
}
